package com.raimcomputing.pickforme.service.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.raimcomputing.pickforme.common.exception.EmailAddressInUseException;
import com.raimcomputing.pickforme.common.exception.InvalidPasswordException;
import com.raimcomputing.pickforme.common.exception.NoSuchUserException;
import com.raimcomputing.pickforme.common.exception.TodoRuntimeException;
import com.raimcomputing.pickforme.common.vo.UserVo;
import com.raimcomputing.pickforme.domain.dao.UserDao;
import com.raimcomputing.pickforme.service.User;
import com.raimcomputing.pickforme.service.utility.PasswordUtility;

public class UserImpl implements User {
	private Log log = LogFactory.getLog( UserImpl.class );
	private UserDao userDao;
	private PasswordUtility passwordUtility;

	/**
	 * 
	 */
	public UserVo createUser( UserVo user, String password )
			throws EmailAddressInUseException {

		assert (user.getEmail() != null) : "Email must be specified to create/update a new user.";

		UserVo currentUser = null;
		try {
			currentUser = userDao.loadUserByEmail( user.getEmail() );
		} catch ( NoSuchUserException e ) {
			// This is expected.
		}

		if ( currentUser != null ) {
			log.info( "Attempted to create user with in-use email '"
					+ user.getEmail() + "'." );
			throw new EmailAddressInUseException();
		}

		// We have an ok address, create password / salt and save it
		user.setSalt( passwordUtility.generateSalt() );
		user.setDigest( passwordUtility.createNewPassword( password, user
				.getSalt() ) );
		userDao.save( user );

		UserVo savedUser = null;
		try {
			savedUser = userDao.loadUserByEmail( user.getEmail() );
		} catch ( NoSuchUserException e ) {
			// This is NOT expected
			log.error( "Saved user not available.", e );
			throw new TodoRuntimeException( "Error saving new user." );
		}

		return (savedUser);
	}

	/**
	 * 
	 */
	public UserVo validateUser( String email, String password )
			throws NoSuchUserException, InvalidPasswordException {

		UserVo user = userDao.loadUserByEmail( email );

		if ( passwordUtility.verifyPassphrase( user, password ) ) {
			return (user);
		} else {
			throw new InvalidPasswordException();
		}
	}

	public void setUserDao( UserDao userDao ) {
		this.userDao = userDao;
	}

	public void setPasswordUtility( PasswordUtility passwordUtility ) {
		this.passwordUtility = passwordUtility;
	}

}
